package com.moodswings;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.google.android.maps.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Activity za mapu. Povezuje se sa serverom, pokupi informacije u obliku JSON stringa i onda ih koristi da iscrta markere
 * po mapi. Koristi MoodItemizedOverlay da crta overlay na mapi.
 */
public class MoodMapActivity extends MapActivity {
	private MapController mapController;
	MoodItemizedOverlay itemizedoverlay;
	MapView mapView;

	/**
	 * Prilikom kreiranja iscrta mapu i fokusira se na odredjenu tacku. Kreira overlay sa default ikonicom za marker
	 * (koja se kasnije menja u zavisnosti od raspolozenja)
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.map);


		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);

		mapController = mapView.getController();

		GeoPoint geoPoint = new GeoPoint(44820600, 20462200);
		mapController.setCenter(geoPoint);
		mapController.animateTo(geoPoint);

		List<Overlay> mapOverlays = mapView.getOverlays();
		Drawable drawable = this.getResources().getDrawable(R.drawable.happysmall);
		itemizedoverlay = new MoodItemizedOverlay(drawable, this);
		mapOverlays.add(itemizedoverlay);

	}

	/**
	 * Poziva getData koji nalazi informacije i crta po mapi
	 */
	@Override
	protected void onResume() {
		super.onResume();
		getData();
	}


	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Pomocna metoda, odredjuje koja ce se ikonica iscrtavati na mapi u zavisnosti od moodId parametra (tj od raspolozenja)
	 *
	 */
	public Drawable getDrawing(int moodId) {

		Drawable icon = this.getResources().getDrawable(R.drawable.happy);
		switch (moodId) {

			case 1:
				icon = this.getResources().getDrawable(R.drawable.happysmall);
				break;
			case 2:
				icon = this.getResources().getDrawable(R.drawable.sadsmall);
				break;
			case 3:
				icon = this.getResources().getDrawable(R.drawable.lonelysmall);
				break;
			case 4:
				icon = this.getResources().getDrawable(R.drawable.angrysmall);
				break;
			case 5:
				icon = this.getResources().getDrawable(R.drawable.lovesmall);
				break;
			case 6:
				icon = this.getResources().getDrawable(R.drawable.smilesmall);
				break;
		}
		return icon;
	}

	/**
	 * Glavna metoda za crtanje. Koristi JSONArray, uzima jedan po jedan element i koristi ga da iscrta markere po mapi
	 * sa odgovarajucim podacima (ime korisnika i datum) i odgovarajucom ikonicom.
	 */
	public void draw(JSONArray result) throws JSONException {
		itemizedoverlay.clear();

		int len = result.length();

		for (int i = 0; i < len; i++) {
			JSONObject jsonObject = (JSONObject) result.get(i);
			String temp = jsonObject.get("longitude").toString();  //uzima JSONObject i pretvara ga u String
			Float longitudex = Float.parseFloat(temp);             //a onda String parsuje u odgovarajuce velicine
			temp = jsonObject.get("latitude").toString();
			Float latitudex = Float.parseFloat(temp);
			latitudex *= 1000000;
			longitudex *= 1000000;
			Integer longitude = Math.round(longitudex);             //longitude i latitude koji su potrebni za GeoPoint
			Integer latitude = Math.round(latitudex);               //dobija zaokruzivanjem float vrednosti pomnozene sa
			GeoPoint geoPoint = new GeoPoint(latitude, longitude);  //milion (sto odgovara GeoPoint dimenzijama)

			Long time = Long.parseLong(jsonObject.get("time").toString());
			Date date = new Date(time);
			SimpleDateFormat sdf = new SimpleDateFormat("dd:MM:yyyy hh:mm:ss"); //vreme ne predstavljamo u milisekundama
			String sDate = sdf.format(date);                                    //proteklim od 1970 nego kao datum i vreme


			OverlayItem overlayitem1 = new OverlayItem(geoPoint, jsonObject.get("userId").toString(),
					sDate);


			Drawable icon = getDrawing(Integer.parseInt(jsonObject.get("moodId").toString()));

			icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());   //postavljamo granice ikonice markera
			overlayitem1.setMarker(icon);
			itemizedoverlay.addOverlay(overlayitem1);                                    //dodajemo
		}


		mapView.postInvalidate();     //refreshujemo mapu, iscrtamo sve nove podatke

	}

	/**
	 * pokupi ip adresu servera iz preferenci, posalje zahtev, prihvati odgovor u vidu JSONArray-a i prosledi ga draw() metodi
	 */
	public void getData() {

		SharedPreferences settings = getSharedPreferences(MoodSwingsActivity.PREF_NAME, Context.MODE_PRIVATE); //preference
		String IP = settings.getString("IP", "192.168.1.3:8080");
		final String ip = "http://" + IP + "/map";

		AsyncTask<URL, Void, Void> a = new AsyncTask<URL, Void, Void>() { //u pozadini komunicira sa serverom
			protected Void doInBackground(URL... urls) {

				HttpClient httpclient = new DefaultHttpClient();
				HttpGet httpGet = new HttpGet(ip);

				HttpResponse response = null;

				try {
					response = httpclient.execute(httpGet);

				} catch (Exception e) {
					Log.e("MSW", "e", e);
				}

				try {
					BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
					StringBuilder builder = new StringBuilder();
					for (String line = null; (line = reader.readLine()) != null; ) {
						builder.append(line).append("\n");
					}

					JSONTokener tokener = new JSONTokener(builder.toString()); //dobio je json string kao odgovor,
					JSONArray finalResult = new JSONArray(tokener);            // sada ga preoblikuje u JSONArray
					draw(finalResult);                                         // i prosledjuje ga draw() metodi koja crta
				} catch (Exception e) {
					Log.e("MSW", "e", e);
				}

				return null;
			}                                          // ne vraca nista, samo treba da posalje upit i iscrta
		}.execute();

	}

}